import {Injectable} from '@nestjs/common';
import {InjectRepository} from "@nestjs/typeorm";
import {Repository} from "typeorm";
import {MemberEntity} from "./member.entity";
import {ResultVo} from "../../vo/common/result.vo";
import {UserLoginReqVo} from 'src/vo/member/user-login-req.vo';
import {LoginWayEnum} from 'src/enum/login-way.enum';
import {RedisUtils} from 'src/utils/redis.utils';
import {v4 as uuidv4} from 'uuid';
import {GetRandomNum} from 'src/utils/common.utils';
import {ApiCodeEnum} from 'src/enum/api-code.enum';
import {UserCodeReqVo} from 'src/vo/member/user-code-req.vo';
import {UserRegisterReqVo} from 'src/vo/member/user-register-req.vo';
import {EnableStatusEnum} from 'src/enum/enable-status.enum';
import {PayPasswordVo} from "../../vo/member/pay-password.vo";
import {Md5} from "ts-md5";

@Injectable()
export class MemberService {
    constructor(
        @InjectRepository(MemberEntity)
        private readonly memberRepository: Repository<MemberEntity>,

        private readonly redis: RedisUtils
    ) { }

    async register(userRegisterReqVo: UserRegisterReqVo) {
        console.log("用户注册");
        // 查询用户是否存在
        if (!userRegisterReqVo.mobile && !userRegisterReqVo.email) {
            return ResultVo.exception(ApiCodeEnum.MOBILE_OR_EMAIL_MISS)
        }
        if (userRegisterReqVo.mobile) {
            const isExist = await this.memberRepository.findOne({ mobile: userRegisterReqVo.mobile })
            if (isExist) return ResultVo.exception(ApiCodeEnum.USER_EXIST)
        }

        if (userRegisterReqVo.email) {
            const isExist = await this.memberRepository.findOne({ email: userRegisterReqVo.email })
            if (isExist) return ResultVo.exception(ApiCodeEnum.USER_EXIST)
        }
        let member = new MemberEntity()
        member.nickName = userRegisterReqVo.nickName
        member.avatar = userRegisterReqVo.avatar
        member.mobile = userRegisterReqVo.mobile
        member.email = userRegisterReqVo.email
        member.status = EnableStatusEnum.ENABLE
        member.levelId = 0
        const res = await this.memberRepository.save(member)
        console.log("注册用户成功:", res);
        return ResultVo.success()
    }
    async getUserInfo(token: string) {
        if (!token) return ResultVo.exception(ApiCodeEnum.PARAM_ERROR)
        let userStr = await this.redis.get(token)
        if (userStr) {
            return ResultVo.successWithData(JSON.parse(userStr))
        }
        return ResultVo.exception(ApiCodeEnum.TOKEN_EXPIRE)
    }

    async getCode(userCodeReqVo: UserCodeReqVo) {
        console.log("获取验证码：", userCodeReqVo);
        const code = GetRandomNum(1000, 9999)
        if (userCodeReqVo.loginWay == LoginWayEnum.MOBILE_LOGIN) {
            // 手机号登陆
            const oldCode = await this.redis.get(userCodeReqVo.mobile)
            if (oldCode) {
                return ResultVo.fail("您已经获取了验证码，请勿重复获取")
            }
            await this.redis.set(userCodeReqVo.mobile, code, 60)
            return ResultVo.successWithData({ code: code })
        } else if (userCodeReqVo.loginWay == LoginWayEnum.EMAIL_LOGIN) {
            // 邮箱登陆
            const oldCode = await this.redis.get(userCodeReqVo.email)
            if (oldCode) {
                return ResultVo.fail("您已经获取了验证码，请勿重复获取")
            }
            await this.redis.set(userCodeReqVo.email, code, 60)
            return ResultVo.successWithData({ code: code })
        }
        return ResultVo.fail("暂不支持的登陆方式")
    }

    async login(userLoginReqVo: UserLoginReqVo) {
        // 判断用户登陆方式
        if (userLoginReqVo.loginWay == LoginWayEnum.MOBILE_LOGIN && userLoginReqVo.mobile && userLoginReqVo.verificationCode) {
            // 手机号登陆
            // 验证验证码是否正确
            const code = userLoginReqVo.verificationCode
            const oldCode = await this.redis.get(userLoginReqVo.mobile)
            console.log(`验证码:code ${code} oldCode:${oldCode}`);
            if (oldCode != code) {
                return ResultVo.exception(ApiCodeEnum.CODE_ERROR)
            }
            // 查询用户信息
            let user = await this.memberRepository.findOne({ mobile: userLoginReqVo.mobile })
            if (!user) {
                // 注册用户
                let registerVo = new UserRegisterReqVo()
                registerVo.mobile = userLoginReqVo.mobile
                registerVo.nickName = "会员" + code
                registerVo.avatar = "http://23.224.198.161:3000/images/1653376292074.png"
                await this.register(registerVo)
                user = await this.memberRepository.findOne({ mobile: userLoginReqVo.mobile })
            }
            user.password = ""
            await this.memberRepository.update({ id: user.id }, { lastLoginTime: new Date() })
            console.log("查询到用户信息", user);
            if (!user) {
                return ResultVo.exception(ApiCodeEnum.USER_NOT_EXIST)
            }
            // 保存token
            const token = uuidv4()
            await this.redis.set(token, JSON.stringify(user), 24 * 60 * 60)
            // 删除验证码
            await this.redis.del(userLoginReqVo.mobile)
            return ResultVo.successWithData({ token, ...user })
        } else if (userLoginReqVo.loginWay == LoginWayEnum.EMAIL_LOGIN) {
            // 邮箱登陆
        } else if (userLoginReqVo.loginWay == LoginWayEnum.WX_LOGIN) {
            // 微信登陆
        } else {
            // 不支持的登陆方式
            return ResultVo.exception(ApiCodeEnum.NOT_SUPPORT_LOGIN_WAY)
        }
    }

    async queryAll() {
        let data = await this.memberRepository.find()
        return ResultVo.successWithData(data)
    }

    async queryOne(id: number | string) {
        let data = await this.memberRepository.findOne(id)
        return ResultVo.successWithData(data)
    }

    async add(data: MemberEntity) {
        let date = new Date()
        data.createdTime = date
        data.updatedTime = date
        let res = await this.memberRepository.save<MemberEntity>(data)
        return ResultVo.successWithData(res)
    }

    async edit(data: MemberEntity) {
        data.updatedTime = new Date()
        let res = await this.memberRepository.update({ id: data.id }, data)
        return ResultVo.successWithData(res)
    }

    async delete(id: number | string) {
        let res = await this.memberRepository.delete(id)
        return ResultVo.successWithData(res)
    }

    async checkPayPassword(userId: number) {
        let userInfo = await this.memberRepository.findOne(userId)
        if(!userInfo){
            return ResultVo.exception(ApiCodeEnum.USER_NOT_EXIST)
        }
        if(!userInfo.payPassword){
            return ResultVo.exception(ApiCodeEnum.PAY_PASS_NOT_EXIST)
        }
        return ResultVo.success()
    }

    async setPayPassword(payPasswordVo: PayPasswordVo) {
        // 设置用户支付密码
        // 查询用户
        let userInfo = await this.memberRepository.findOne(payPasswordVo.userId)
        if(!userInfo){
            return ResultVo.exception(ApiCodeEnum.USER_NOT_EXIST)
        }

        // 校验验证码是否正确
        const code = payPasswordVo.verificationCode
        const oldCode = await this.redis.get(payPasswordVo.mobile)
        console.log(`验证码:code ${code} oldCode:${oldCode}`);
        if (oldCode != code) {
            return ResultVo.exception(ApiCodeEnum.CODE_ERROR)
        }

        let payPassword = Md5.hashStr(payPasswordVo.payPassword)
        userInfo.payPassword = payPassword
        // 更新支付密码
        let res = this.memberRepository.update({id:userInfo.id},{payPassword})
        return ResultVo.successWithData(res)
    }
}
